import CryptoJS from 'crypto-js';

// This should be stored securely and not hardcoded in production
// In a real app, this should be fetched from a secure endpoint or environment variable
const ENCRYPTION_KEY = process.env.REACT_APP_ENCRYPTION_KEY || 'default-secret-key-change-in-production';

// AES encryption function
export const encryptData = (data) => {
  try {
    const jsonString = typeof data === 'string' ? data : JSON.stringify(data);
    const encrypted = CryptoJS.AES.encrypt(jsonString, ENCRYPTION_KEY).toString();
    return encrypted;
  } catch (error) {
    console.error('Encryption error:', error);
    throw new Error('Failed to encrypt data');
  }
};

// AES decryption function
export const decryptData = (encryptedData) => {
  try {
    const bytes = CryptoJS.AES.decrypt(encryptedData, ENCRYPTION_KEY);
    const decryptedString = bytes.toString(CryptoJS.enc.Utf8);
    
    if (!decryptedString) {
      throw new Error('Decryption failed: Invalid result');
    }
    
    // Try to parse as JSON, if fails return as string
    try {
      return JSON.parse(decryptedString);
    } catch {
      return decryptedString;
    }
  } catch (error) {
    console.error('Decryption error:', error);
    throw new Error('Failed to decrypt data');
  }
};

// Generate a random initialization vector (IV) for more secure encryption
export const generateIV = () => {
  return CryptoJS.lib.WordArray.random(16).toString();
};

// Encrypt with IV for enhanced security
export const encryptWithIV = (data, iv) => {
  try {
    const jsonString = typeof data === 'string' ? data : JSON.stringify(data);
    const key = CryptoJS.enc.Utf8.parse(ENCRYPTION_KEY);
    const ivParsed = CryptoJS.enc.Hex.parse(iv);
    
    const encrypted = CryptoJS.AES.encrypt(jsonString, key, {
      iv: ivParsed,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    });
    
    return encrypted.toString();
  } catch (error) {
    console.error('Encryption with IV error:', error);
    throw new Error('Failed to encrypt data with IV');
  }
};

// Decrypt with IV for enhanced security
export const decryptWithIV = (encryptedData, iv) => {
  try {
    const key = CryptoJS.enc.Utf8.parse(ENCRYPTION_KEY);
    const ivParsed = CryptoJS.enc.Hex.parse(iv);
    
    const decrypted = CryptoJS.AES.decrypt(encryptedData, key, {
      iv: ivParsed,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    });
    
    const decryptedString = decrypted.toString(CryptoJS.enc.Utf8);
    
    if (!decryptedString) {
      throw new Error('Decryption failed: Invalid result');
    }
    
    // Try to parse as JSON, if fails return as string
    try {
      return JSON.parse(decryptedString);
    } catch {
      return decryptedString;
    }
  } catch (error) {
    console.error('Decryption with IV error:', error);
    throw new Error('Failed to decrypt data with IV');
  }
};

// Hash function for passwords (using SHA-256)
export const hashPassword = (password) => {
  try {
    return CryptoJS.SHA256(password).toString();
  } catch (error) {
    console.error('Password hashing error:', error);
    throw new Error('Failed to hash password');
  }
};

// Create a secure payload with encrypted data and IV
export const createSecurePayload = (data) => {
  try {
    const iv = generateIV();
    const encryptedData = encryptWithIV(data, iv);
    
    return {
      data: encryptedData,
      iv: iv,
      timestamp: new Date().toISOString()
    };
  } catch (error) {
    console.error('Secure payload creation error:', error);
    throw new Error('Failed to create secure payload');
  }
};

// Extract and decrypt data from a secure payload
export const extractSecurePayload = (payload) => {
  try {
    if (!payload || !payload.data || !payload.iv) {
      throw new Error('Invalid secure payload format');
    }
    
    return decryptWithIV(payload.data, payload.iv);
  } catch (error) {
    console.error('Secure payload extraction error:', error);
    throw new Error('Failed to extract secure payload');
  }
};